/*select_client.c 2011.9.2 by yyg*/  
#include <stdio.h>  
#include <stdlib.h>  
#include <errno.h>  
#include <string.h>  
#include <sys/types.h>  
#include <sys/stat.h>
#include <netinet/in.h>  
#include <sys/socket.h>  
#include <sys/wait.h>  
#include <pthread.h>  
#include <sys/time.h>  
#include <arpa/inet.h>  
#include <unistd.h>  
#include <fcntl.h>
#include <resolv.h>

#include "util.h"
#define LISTENQ 5
#define MAXLINE 4096
#define MAXMEM 2

int listenfd,connfd[MAXMEM];//分别记录服务器端的套接字与连接的多个客户端的套接字

void quit();//服务器关闭函数
void rcv_snd(int n);//服务器接收并转发消息函数

int main()
{
    pthread_t thread;
    struct sockaddr_in servaddr,cliaddr;
    socklen_t len;
    time_t ticks;
    char buff[MAXLINE];
    int i;
	
	//create server socket
    listenfd=socket(AF_INET,SOCK_STREAM,0);
    if(listenfd<0)
    {
        printf("Socket created failed.\n");
        return -1;
    }

    servaddr.sin_family=AF_INET;
    servaddr.sin_port=htons(3567);
    servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
    if(bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
    {
        printf("Bind failed.\n");
        return -1;
    }

    listen(listenfd, LISTENQ);

    pthread_create(&thread,NULL,(void*)(&quit),NULL);

    for(i=0;i < MAXMEM ;i++)
        connfd[i]=-1;

    while(1)
    {
        len=sizeof(cliaddr);
        for(i=0;i<MAXMEM;i++)
        {
            if(connfd[i]==-1)
            {
                break;
            }
        }

        connfd[i]=accept(listenfd,(struct sockaddr*)&cliaddr,&len);

        pthread_create(malloc(sizeof(pthread_t)),NULL,(void*)(&rcv_snd),(void*)i);

    }
    return 0;
}

void quit()
{
    char msg[10];
    while(1)
    {
        scanf("%s",msg);
        if(strcmp("quit",msg)==0)
        {
            printf("Byebye...\n");
            close(listenfd);
            exit(0);
        }
    }
}

void rcv_snd(int n)
{
    char buffer[MAXLINE];
	char objfile[MAXLINE], argv[MAXLINE] = "cd ";
    int len = 3, ret = 0;
	fd_set rfds;
	int retval, objfd = 0, sockfd = connfd[n];
	
    printf("client %d\n",n);
	// read pwd
	ret = read(sockfd, argv + len, MAXLINE - len);
	if(ret < 0) {
		fprintf(stderr, "Read error when waiting for PWD");
		retval = -1;
		goto error_out;
	}
	strncpy(objfile, argv +len, ret);

	len += ret;
	strncpy(argv + len, " ; ", 3);
	len += 3;
	ret = write(sockfd, "copy", 4);
	if(len < 0) {
		fprintf(stderr, "write error when replay PWD");
		retval = -1;
		goto error_out;
	}
	//read compile orders
	ret = read(sockfd, argv + len, MAXLINE-len) ;
	if(ret < 0) {
		fprintf(stderr, "Read error when waiting for PWD");
		retval = -1;
		goto error_out;
	}
	len += ret;
	ret = write(sockfd, "copy", 4);
	if(ret < 0) {
		fprintf(stderr, "client %d write error when replay PWD", n);
		retval = -1;
		goto error_out;
	}
	printf("%s\n", argv);
	ret = dbd_get_target_obj(argv, objfile + strlen(objfile));
	//compile files
	ret = system(argv);
	
	if(ret < 0){
		fprintf(stderr, "client %d Compile failed\n",n);
		retval = -1;
		goto error_out;
	}
	
	if ((objfd = open(objfile, O_RDONLY)) == -1) {
		fprintf(stderr, "client %d open obj file failed %s\n",n, objfile);
		retval = -1;
		goto error_out;
	}
	while((ret = read(objfd, buffer, MAXLINE)) >0){
    	len = write(sockfd, buffer, ret);
    	if(len < 0){
        	fprintf(stderr, "client %d send obj file fail.the errno is:%d,error info is %s.\n",n,errno,strerror(errno));
			retval = -1;
			goto error_out;
		}
	}
	if(ret < 0){
		fprintf(stderr, "client %d read obj file failed %s\n", n, objfile);
		retval = -1;
	}

error_out:
	if(retval <0)
		write(sockfd, "bye", 3);
	else 
		write(sockfd, "succ", 4);
    close(sockfd);
	close(objfd);
    connfd[n]=-1;
    pthread_exit(&retval);
}
